package com.specialized.passenger.compent;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.specialized.common.redis.service.RedisService;
import lombok.extern.log4j.Log4j2;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Map;

/**
 * @Author：djh
 * @Package：com.specialized.passenger.controller
 * @Project：Specialized-Cloud
 * @name：ChatMsgServer
 * @Date：2024/7/22 19:51
 */
@ServerEndpoint(value = "/chatmsg/{username}")
@Component
@Log4j2
public class ChatMsgServer {

    private static  ApplicationContext applicationContext;

    public static void   setApplicationContext(ApplicationContext applicationContext){
        ChatMsgServer.applicationContext = applicationContext;
    }

    private RedisService redisService;





    public static final String COUNT="online";

    public static final String SESSIONMAP="sessionMap";

    @OnOpen
    public void onOpen(Session session, @PathParam("username") String username){
        RedisService redisService = applicationContext.getBean(RedisService.class);
        redisService.setCacheMapValue(SESSIONMAP,username,session);
        Map<String, Session> cacheMap = redisService.getCacheMap(SESSIONMAP);
        log.info("{}用户已上线,当前在线人数为:{}",username,cacheMap.size());
        JSONObject result = new JSONObject();
        JSONArray array = new JSONArray();
        for (String key : cacheMap.keySet()) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.set("username",key);
            array.add(jsonObject);
        }
        result.set("users",array);
        sendAllMessage(result.toString(),cacheMap);
    }


    @OnClose
    public void onClose(Session session,@PathParam("username") String username){
        RedisService redisService = applicationContext.getBean(RedisService.class);
        redisService.deleteCacheMapValue(SESSIONMAP,username);
        log.info("{}用户下线,当前在线人数:{}",username,redisService.getCacheMap(SESSIONMAP).size());
    }

    @OnError
    public void onError(Session session, Throwable error) {
        log.error("发生错误");
        error.printStackTrace();
    }

    @OnMessage
    public void onMEssage(String message,Session session,@PathParam("username")String username){
        RedisService redisService = applicationContext.getBean(RedisService.class);
        JSONObject entries = JSONUtil.parseObj(message);
        String touser = entries.getStr("to");
        String text = entries.getStr("text");
        log.info("服务端收到{} 发送给{} 的消息{}",username,touser,text);
        Session tosession = redisService.getCacheMapValue(SESSIONMAP, touser);
        if (tosession!=null){
            JSONObject mess = new JSONObject();
            mess.set("from",username);
            mess.set("text",text);
            sendMessage(mess.toString(),tosession);
        } else {
            log.info("发送失败,未找到对应的用户");
        }
    }

    private void sendMessage(String mess, Session tosession) {
        log.info("服务端向{}发送消息{}",tosession.getId(),mess);
        try {
            //通过客户端的session获取给客户端发送消息的接口方法
            RemoteEndpoint.Basic basicRemote = tosession.getBasicRemote();
            //发送消息给客户端
            basicRemote.sendText(mess);
        } catch (IOException e) {
            log.info("服务端向{}发送消息失败,失败信息:{}",tosession.getId(),e);
        }
    }


    //推送消息给所有客户端
    private void sendAllMessage(String result, Map<String, Session> cacheMap) {
        for (Session session : cacheMap.values()) {
            log.info("服务端给客户端[{}]发送消息:[{}]",session.getId(),result);
            try {
                //通过客户端的session获取给客户端发送消息的接口方法
                RemoteEndpoint.Basic basicRemote = session.getBasicRemote();
                //发送消息给客户端
                basicRemote.sendText(result);
            } catch (IOException e) {
                log.info("服务端向[{}]发送消息失败:{}",cacheMap,e);
            }
        }
    }


}
